package com.zboot.zbootadmin.common.aspect;

import com.alibaba.fastjson.JSON;
import com.zboot.zbootadmin.common.security.service.TokenService;
import com.zboot.zbootadmin.common.utils.DateUtils;
import com.zboot.zbootadmin.common.utils.ServletUtils;
import com.zboot.zbootadmin.project.system.log.entity.SysLog;
import com.zboot.zbootadmin.project.system.log.service.SysLogService;
import com.zboot.zbootadmin.project.system.user.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author: zyt
 * @Description:日志处理
 * @Date: Created in 21:39 2020/5/28
 */
@Aspect
@Component
@Slf4j
public class LogAspect {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysLogService sysLogService;

    @Pointcut("@annotation(com.zboot.zbootadmin.common.annotation.Log)") //切点
    public void webRequestLog() {
    }

    @Pointcut("@annotation(com.zboot.zbootadmin.common.annotation.Log)") //切点
    public void webExceptionLog() {
    }

    /*@Before("webRequestLog()",returning="returnValue")*/
    @AfterReturning(returning = "ret",pointcut = "webRequestLog()")
    public void beforeRequest(JoinPoint joinPoint,Object ret) {
       insertSysLog(joinPoint,ret);
    }

    @AfterThrowing(pointcut = "webRequestLog()", throwing = "e")
    public void afterRequest(JoinPoint joinPoint,Exception e) {
       insertSysLog(joinPoint,stackTraceToString(e,e.getStackTrace()));
    }

    public String stackTraceToString( Exception e ,StackTraceElement[] elements) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(e.toString()).append("<br>");
        for (StackTraceElement stet : elements) {
            stringBuffer.append(stet.getClassName()).append(".")
                    .append(stet.getMethodName())
                    .append("(").append(stet.getFileName()).append(":").append(stet.getLineNumber())
                    .append(")<br>");
        }
     return String.valueOf(stringBuffer);
    }

    protected void insertSysLog(JoinPoint joinPoint,Object msg) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request= attributes.getRequest();
        SysUser user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        SysLog sysLog = new SysLog();
        sysLog.setApiAddress(request.getRequestURI());
        sysLog.setCreateTime(DateUtils.parseDate(DateUtils.getDate()));
        sysLog.setIp(request.getRemoteAddr());
        sysLog.setMethod(joinPoint.getSignature().getName());
        sysLog.setMsg(JSON.toJSONString(msg));
        sysLog.setOperator(user==null?"":user.getUserName());
        sysLog.setPath(String.valueOf(request.getRequestURL()));
        sysLog.setRequestClassName(joinPoint.getSignature().getDeclaringTypeName());
        sysLog.setRequestWay(request.getMethod());
        sysLog.setUpdateTime(DateUtils.parseDate(DateUtils.getDate()));
        sysLogService.save(sysLog);
    }
}

